package com.lyf.boot.utils;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReflectUtil;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author Luyufan
 * @date 2023/7/7 9:09
 */
public class TreeUtil {

    /**
     * list转tree
     * @param list 集合
     * @param rootValue 跟节点值
     * @param idName id字段名
     * @param parentName parentId字段名
     * @param childrenName 子节点名称
     * @return list
     */
    public static <T> List<T> buildTree(List<T> list, Object rootValue, String idName, String parentName, String childrenName){
        return list.stream().filter(t -> {
            Object parentValue = ReflectUtil.getFieldValue(t, parentName);
            return ObjectUtil.equals(parentValue, rootValue);
        }).peek(sub -> ReflectUtil.setFieldValue(sub, childrenName, getChildren(sub, list, idName, parentName, childrenName))).collect(Collectors.toList());
    }

    /**
     * 获取子节点
     * @param root 当前节点
     * @param all 所有数据
     * @param idName id字段名
     * @param parentName parentId字段名
     * @param childrenName 子节点名称
     * @return list
     */
    private static <T> List<T> getChildren(T root, List<T> all,String idName, String parentName, String childrenName) {
        List<T> children = all.stream().filter(m -> {
            Object parentId = ReflectUtil.getFieldValue(m, parentName);
            Object rootId = ReflectUtil.getFieldValue(root, idName);
            return ObjectUtil.equals(parentId, rootId);
        }).peek(sub -> ReflectUtil.setFieldValue(sub, childrenName, getChildren(sub, all, idName, parentName, childrenName))).collect(Collectors.toList());
        //前端组件问题，如果children为空集合，即前端为空数组，则需设置为null，否则前端会显示属性图标（+）
        return CollUtil.isEmpty(children) ? null : children;
    }

    /**
     * tree转list
     * @param treeList tree集合
     * @param rootValue 根节点
     * @param idName id字段名
     * @param parentName 父级字段名
     * @param childrenName 子节点字段名
     * @return list
     */
    public static <T> List<T> toList(List<T> treeList, Object rootValue, String idName, String parentName, String childrenName){
        //将tree类型集合转成普通集合
        return treeList.stream().flatMap(t -> {
            List<T> children = (List<T>) ReflectUtil.getFieldValue(t, childrenName);
            if(children != null && !children.isEmpty()){
                return toList(children, rootValue, idName, parentName, childrenName).stream();
            }
            return children.stream();
        }).collect(Collectors.toList());
    }
}
